package com.jg.visitor.filter;

import cn.hutool.core.util.HexUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.symmetric.AES;
import com.jg.visitor.GlobalConst;
import com.jg.visitor.common.utils.JsonService;
import com.jg.visitor.common.wrapper.RequestWrapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Base64;
import java.util.Map;


@WebFilter(filterName="EncryptFilter",urlPatterns="/api/reception/in-out")
@Order(4)
@Slf4j
public class EncryptFilter implements Filter {
    @Resource
    private JsonService jsonService;

    @Override
    public void init(FilterConfig filterConfig) {
        log.info("init");
    }

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        //转换自己的wrapper，实现多次读写
        RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);

        //跨域请求放开
        if("OPTIONS".equalsIgnoreCase(requestWrapper.getMethod())){
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS");
            response.addHeader("Access-Control-Allow-Headers", "*");
            response.setStatus(200);
            filterChain.doFilter(servletRequest, response);
            return;
        }

        //GET请求不加密
        if (requestWrapper.getMethod().equals("GET")) {
            filterChain.doFilter(requestWrapper, servletResponse);
            return;
        }

        //读出json请求体
        StringBuilder buffer = new StringBuilder();
        String line;
        BufferedReader reader;
        reader = requestWrapper.getReader();
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }

        //json字符转对象
        Map<String,String> dataMap = jsonService.jsonToObject(buffer.toString(), Map.class,String.class,String.class);

        //AES加密得到的密文
        String data = dataMap.get("dataStr");
        //加密后的aesKey
        String aesKey = dataMap.get("aesKeyRsaStr");

        RSA rsa = new RSA(GlobalConst.RSA_PRIVATE_KEY,GlobalConst.RSA_PUBLIC_KEY);
        //解密aesKey，得到16进制的aesKey字节数组
        byte[] decode = Base64.getDecoder().decode(aesKey);
        byte[] decrypt1 = rsa.decrypt(decode, KeyType.PrivateKey);

        //16进制转为正常字符串
        String normalKey = hexStr2Str(new String(decrypt1));
        log.info("normalKey ====> {}",normalKey);

        //通过正常的key字符串与iv得到 AES对象
        AES aes = new AES("CBC", "PKCS7Padding",
                // 密钥，可以自定义
                normalKey.getBytes(),
                // iv加盐，按照实际需求添加
                GlobalConst.IV.getBytes());

        //解密16进制数据字符串
        String dataJsonStr = aes.decryptStr(data);

        //重新给请求提设置字节数组
        requestWrapper.setBody(dataJsonStr.getBytes());

        filterChain.doFilter(requestWrapper,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("destroy");
    }

    public static String hexStr2Str(String hexStr) {
        String str = "0123456789ABCDEF";
        char[] hex = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hex[2 * i]) * 16;
            n += str.indexOf(hex[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes);
    }
}
